package com.andatsoft.laisim.activity.setting;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.StreamCorruptedException;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewManager;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.andatsoft.laisim.R;
import com.andatsoft.laisim.activity.BaseActivity;
import com.andatsoft.laisim.asynctask.SongScanner;
import com.andatsoft.laisim.db.DataBaseAccess;
import com.andatsoft.laisim.dialog.FileExtensionDialog;
import com.andatsoft.laisim.dialog.MessageBox;
import com.andatsoft.laisim.dialog.ScanFolderDialog;
import com.andatsoft.laisim.entity.Song;
import com.andatsoft.laisim.service.PlayerService;
import com.andatsoft.laisim.utils.Common;
import com.andatsoft.laisim.utils.ToastMessage;
import com.andatsoft.laisim.view.MyViewFlipper;
import com.andatsoft.laisim.view.SlimProgressBar;
import com.andatsoft.laisim.view.SlimProgressBar.SlimProgressClicked;
import com.andatsoft.laisim.view.WPProgressBar;

public class LibrarySettingActivity extends BaseActivity {

	private LinearLayout mLayoutSelectFolder;
	private LinearLayout mLayoutScan;
	private LinearLayout mLayoutFullScan;
	private LinearLayout mLayoutAutoScan;
	private LinearLayout mLayoutFileExt;
	private LinearLayout mLayoutFileSize;
	private LinearLayout mLayoutRescanTags;
	private MyViewFlipper mViewFileSize;
	private WPProgressBar mWPProgressBar;
	private MessageBox mMessageBox;
	private Button mBtnOk;
	private TextView mTvFileSizeVal, mTvFileSize;
	private SlimProgressBar mSlimProgress;

	private boolean mIsMessageBoxShowing;
	private boolean mIsMessageBoxReady = true;
	private int mFileSize = 100;
	private int mTempFileSize = 100;

	// private PlayerService mPlayerService;
	// private boolean mIsBoundService;
	// private ServiceConnection mPlayerServiceConnection = new
	// ServiceConnection() {
	//
	// @Override
	// public void onServiceDisconnected(ComponentName name) {
	// mPlayerService = null;
	// Log.d("SerConnect", "Disconnect");
	// }
	//
	// // called when bind service called.
	// @Override
	// public void onServiceConnected(ComponentName name, IBinder service) {
	// mPlayerService = ((PlayerService.LocalBinder) service).getService();
	// Log.d("SerConnect", "Main activity Connected");
	//
	// }
	// };
	//
	// public void doBindService() {
	// bindService(
	// new Intent(LibrarySettingActivity.this, PlayerService.class),
	// mPlayerServiceConnection, Context.BIND_AUTO_CREATE);
	// // Log.d("Bind", "bind" + bo);
	// mIsBoundService = true;
	// }
	//
	// public void doUnBindService() {
	// unbindService(mPlayerServiceConnection);
	// mIsBoundService = false;
	// }

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setting_library);
		initViews();
		restoreUIFromSetting();
		setupListeners();
	}

	@Override
	protected void onResume() {
		super.onResume();
		// if (!mIsBoundService)
		// doBindService();
	}

	@Override
	protected void onPause() {
		super.onPause();
		// if (mIsBoundService)
		// doUnBindService();
	}

	private void initViews() {
		mLayoutSelectFolder = (LinearLayout) findViewById(R.id.layout_setting_lib_select_folder);
		mLayoutScan = (LinearLayout) findViewById(R.id.layout_setting_lib_scan);
		mLayoutFullScan = (LinearLayout) findViewById(R.id.layout_setting_lib_full_scan);
		mLayoutAutoScan = (LinearLayout) findViewById(R.id.layout_setting_lib_auto_scan);
		mLayoutFileExt = (LinearLayout) findViewById(R.id.layout_setting_lib_file_ext);
		mLayoutFileSize = (LinearLayout) findViewById(R.id.layout_setting_lib_file_size);
		mLayoutRescanTags = (LinearLayout) findViewById(R.id.layout_setting_lib_rescan_tags);
		mViewFileSize = (MyViewFlipper) findViewById(R.id.view_flipper_setting_lib_file_size);
		mWPProgressBar = (WPProgressBar) findViewById(R.id.wp_progress_scan_setting_lib);
		mBtnOk = (Button) findViewById(R.id.btn_ok_setting_lib_file_size_value);
		mTvFileSize = (TextView) findViewById(R.id.tv_setting_lib_file_size_sub);
		mTvFileSizeVal = (TextView) findViewById(R.id.tv_setting_lib_file_size_value);
		mSlimProgress = (SlimProgressBar) findViewById(R.id.progress_setting_lib_file_size);

		// Setup animation
		mViewFileSize.setInAnimation(AnimationUtils.loadAnimation(
				getApplicationContext(),
				R.anim.slide_right_to_left_fade_in_fast));
		mViewFileSize.setOutAnimation(AnimationUtils.loadAnimation(
				getApplicationContext(),
				R.anim.slide_right_to_left_fade_out_fast));
	}

	private void restoreUIFromSetting() {
		SharedPreferences sp = getSharedPreferences(Common.SP_LIB_SETTING_NAME,
				Context.MODE_PRIVATE);
		mTempFileSize = sp.getInt(Common.SP_LIB_FILE_SIZE, 100);
		mFileSize = mTempFileSize;
		mTvFileSize.setText(String.format(
				getString(R.string.setting_lib_scan_options_file_size_sub),
				mFileSize));

		mSlimProgress.setMax(512);
		mSlimProgress.setProgress(mFileSize);
	}

	private void setupListeners() {
		mLayoutSelectFolder.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);
					startActivity(new Intent(LibrarySettingActivity.this,
							ScanFolderDialog.class));
					return true;
				}
				return false;
			}
		});

		mLayoutScan.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);
					mLayoutScan.setEnabled(false);
					new FolderScanner(getApplicationContext(), false, 0)
							.execute();
					return true;
				case MotionEvent.ACTION_CANCEL:
					v.setBackgroundColor(0xff000000);
					return true;
				}
				return false;
			}
		});

		mLayoutFullScan.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);
					mMessageBox = new MessageBox(getApplicationContext(), true);
					mMessageBox
							.setMessageContent(getString(R.string.setting_lib_message_full_scan));
					mMessageBox
							.setOkButtonOnTouchListener(new OnTouchListener() {

								@Override
								public boolean onTouch(View v, MotionEvent event) {
									if (!mIsMessageBoxReady) {
										return true;
									}
									switch (event.getAction()) {
									case MotionEvent.ACTION_DOWN:
										setAlpha(v, 0.5f);
										return true;

									case MotionEvent.ACTION_UP:
										setAlpha(v, 1.0f);
										mLayoutFullScan.setEnabled(false);
										new FolderScanner(
												getApplicationContext(), true,
												1).execute();
										onBackPressed();
										mIsMessageBoxReady = false;
										break;
									}
									return false;
								}
							});
					mMessageBox
							.setCancelButtonOnTouchListener(new OnTouchListener() {

								@Override
								public boolean onTouch(View v, MotionEvent event) {
									if (!mIsMessageBoxReady) {
										return true;
									}
									switch (event.getAction()) {
									case MotionEvent.ACTION_DOWN:
										setAlpha(v, 0.5f);
										return true;

									case MotionEvent.ACTION_UP:
										setAlpha(v, 1.0f);
										mIsMessageBoxReady = false;
										onBackPressed();
										break;
									}
									return false;
								}
							});

					LinearLayout.LayoutParams pr = new LinearLayout.LayoutParams(
							LinearLayout.LayoutParams.MATCH_PARENT,
							LinearLayout.LayoutParams.MATCH_PARENT);
					addContentView(mMessageBox, pr);
					Animation animation = AnimationUtils.loadAnimation(
							getBaseContext(),
							R.anim.message_box_slide_top_to_bottom_fade_in);
					animation.setStartOffset(0);
					animation.setFillAfter(true);
					mMessageBox.getContent().startAnimation(animation);
					animation = AnimationUtils.loadAnimation(getBaseContext(),
							R.anim.message_box_bg_fade_in_fast);
					animation.setStartOffset(0);
					animation.setFillAfter(true);
					mMessageBox.getBackgroundLayout().startAnimation(animation);
					mIsMessageBoxShowing = true;

					return true;
				case MotionEvent.ACTION_CANCEL:
					v.setBackgroundColor(0xff000000);
					return true;
				}
				return false;
			}
		});

		mLayoutAutoScan.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);

					mMessageBox = new MessageBox(getApplicationContext(), true);
					mMessageBox
							.setMessageContent(getString(R.string.setting_lib_message_auto_scan));
					mMessageBox
							.setOkButtonOnTouchListener(new OnTouchListener() {

								@Override
								public boolean onTouch(View v, MotionEvent event) {
									if (!mIsMessageBoxReady) {
										return true;
									}

									switch (event.getAction()) {
									case MotionEvent.ACTION_DOWN:
										setAlpha(v, 0.5f);
										return true;

									case MotionEvent.ACTION_UP:
										setAlpha(v, 1.0f);
										// reset save folder
										deleteFile("sf.ls");
										mLayoutAutoScan.setEnabled(false);
										new FolderScanner(
												getApplicationContext(), false,
												2).execute();
										onBackPressed();
										mIsMessageBoxReady = false;
										break;
									}
									return false;
								}
							});
					mMessageBox
							.setCancelButtonOnTouchListener(new OnTouchListener() {

								@Override
								public boolean onTouch(View v, MotionEvent event) {
									if (!mIsMessageBoxReady) {
										return true;
									}
									switch (event.getAction()) {
									case MotionEvent.ACTION_DOWN:
										setAlpha(v, 0.5f);
										return true;

									case MotionEvent.ACTION_UP:
										setAlpha(v, 1.0f);
										mIsMessageBoxReady = false;
										onBackPressed();
										break;
									}
									return false;
								}
							});

					LinearLayout.LayoutParams pr = new LinearLayout.LayoutParams(
							LinearLayout.LayoutParams.MATCH_PARENT,
							LinearLayout.LayoutParams.MATCH_PARENT);
					addContentView(mMessageBox, pr);
					Animation animation = AnimationUtils.loadAnimation(
							getBaseContext(),
							R.anim.message_box_slide_top_to_bottom_fade_in);
					animation.setStartOffset(0);
					mMessageBox.getContent().startAnimation(animation);
					animation = AnimationUtils.loadAnimation(getBaseContext(),
							R.anim.fade_in_fast);
					animation.setStartOffset(0);
					mMessageBox.getBackgroundLayout().startAnimation(animation);
					mIsMessageBoxShowing = true;

					return true;
				case MotionEvent.ACTION_CANCEL:
					v.setBackgroundColor(0xff000000);
					return true;
				}
				return false;
			}
		});

		mLayoutFileExt.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);
					startActivity(new Intent(LibrarySettingActivity.this,
							FileExtensionDialog.class));
					return true;
				case MotionEvent.ACTION_CANCEL:
					v.setBackgroundColor(0xff000000);
					return true;
				}
				return false;
			}
		});

		mLayoutFileSize.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);
					mTvFileSizeVal.setText(mTempFileSize + " KB");
					mViewFileSize.setDisplayedChild(1);
					return true;
				case MotionEvent.ACTION_CANCEL:
					v.setBackgroundColor(0xff000000);
					return true;
				}
				return false;
			}
		});
		mSlimProgress.setOnSlimClicked(new SlimProgressClicked() {

			@Override
			public void onClick(int newProgress) {
				mTempFileSize = newProgress;
				mTvFileSizeVal.setText(mTempFileSize + " KB");

			}
		});
		mBtnOk.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				mFileSize = mTempFileSize;
				mTvFileSize.setText(String
						.format(getString(R.string.setting_lib_scan_options_file_size_sub),
								mFileSize));

				// save setting value
				SharedPreferences sp = getSharedPreferences(
						Common.SP_LIB_SETTING_NAME, Context.MODE_PRIVATE);
				SharedPreferences.Editor editor = sp.edit();
				editor.putInt(Common.SP_LIB_FILE_SIZE, mFileSize);
				editor.commit();
				// Setup animation
				mViewFileSize.setInAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_left_to_right_fade_in_fast));
				mViewFileSize.setOutAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_left_to_right_fade_out_fast));
				mViewFileSize.setDisplayedChild(0);

				// re Setup animation
				mViewFileSize.setInAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_right_to_left_fade_in_fast));
				mViewFileSize.setOutAnimation(AnimationUtils.loadAnimation(
						getApplicationContext(),
						R.anim.slide_right_to_left_fade_out_fast));

			}
		});
		mLayoutRescanTags.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					v.setBackgroundColor(0x50ffffff);
					return true;
				case MotionEvent.ACTION_UP:
					v.setBackgroundColor(0xff000000);
					new TagsUpdater().execute();
					return true;
				case MotionEvent.ACTION_CANCEL:
					v.setBackgroundColor(0xff000000);
					return true;
				}
				return false;
			}
		});
	}

	@Override
	public void onBackPressed() {
		if (mIsMessageBoxShowing) {
			Animation animation = AnimationUtils.loadAnimation(
					getBaseContext(),
					R.anim.message_box_slide_bottom_to_top_fade_out);
			animation.setStartOffset(0);
			animation.setFillAfter(true);
			mMessageBox.getContent().startAnimation(animation);
			mMessageBox.getContent().setVisibility(View.INVISIBLE);
			animation = AnimationUtils.loadAnimation(getBaseContext(),
					R.anim.message_box_bg_fade_out_fast);
			animation.setStartOffset(0);
			animation.setFillAfter(true);
			mMessageBox.getBackgroundLayout().startAnimation(animation);
			mMessageBox.getBackgroundLayout().setClickable(false);
			animation.setAnimationListener(new AnimationListener() {

				@Override
				public void onAnimationStart(Animation animation) {

				}

				@Override
				public void onAnimationRepeat(Animation animation) {

				}

				@Override
				public void onAnimationEnd(Animation animation) {
					((ViewManager) mMessageBox.getParent())
							.removeView(mMessageBox);
					mMessageBox = null;
					mIsMessageBoxShowing = false;
					mIsMessageBoxReady = true;
				}
			});
		} else {
			super.onBackPressed();
		}
	}

	class FolderScanner extends SongScanner {

		private int mCommand;

		public FolderScanner(Context c, boolean isFullScan, int cmd) {
			super(c, isFullScan);
			this.mCommand = cmd;
		}

		@Override
		protected void onPreExecute() {
			if (mCommand == 0) {
				// normal scan
				mWPProgressBar.setVisibility(View.VISIBLE);
			} else if (mCommand == 1) {
				((WPProgressBar) findViewById(R.id.wp_progress_full_scan_setting_lib))
						.setVisibility(View.VISIBLE);
			} else {
				((WPProgressBar) findViewById(R.id.wp_progress_auto_scan_setting_lib))
						.setVisibility(View.VISIBLE);
			}
		}

		@Override
		protected Integer[] doInBackground(String[]... params) {
			String[] pr = null;

			Integer[] songFound = null;
			switch (mCommand) {
			case 0:
				// normal scan, scan from saved folder only
				List<String> savedFolder = getSavedFolder();
				if (savedFolder != null && savedFolder.size() > 0) {

					pr = new String[savedFolder.size()];
					for (int i = 0; i < pr.length; i++) {
						pr[i] = savedFolder.get(i);
					}
				}
				songFound = super.doInBackground(pr);
				break;
			case 1:
				// full scan, delete all data and scan all path
				songFound = super.doInBackground(pr);
				break;
			case 2:
				// auto scan, scan all path
				songFound = super.doInBackground(pr);
				break;

			default:
				break;
			}

			// // delete saved playing song
			// DataBaseAccess db = new DataBaseAccess(getApplicationContext());
			// db.deleteSavedPlayingSong();
			// db.close();
			// save lib data
			SharedPreferences sP = getSharedPreferences(Common.SP_LIBRARY_NAME,
					Context.MODE_PRIVATE);
			SharedPreferences.Editor ed = sP.edit();
			ed.putInt(Common.SP_LIBRARY_PLAYING_LIB_INDEX, 2);
			ed.putInt(Common.SP_LIBRARY_PLAYING_SONG_INDEX, 0);
			ed.commit();
			// flag to update song
			// LibraryActivity.isNeedToUpdatePlaylist = true;
			return songFound;
		}

		@SuppressWarnings("unchecked")
		private List<String> getSavedFolder() {
			try {
				FileInputStream fis = openFileInput("sf.ls");
				ObjectInputStream ois = new ObjectInputStream(fis);
				List<String> savedFolder = (List<String>) ois.readObject();
				ois.close();
				fis.close();
				return savedFolder;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (StreamCorruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Integer[] result) {
			if (mCommand == 0) {
				// normal scan
				mWPProgressBar.setVisibility(View.INVISIBLE);
				mLayoutScan.setEnabled(true);
			} else if (mCommand == 1) {
				((WPProgressBar) findViewById(R.id.wp_progress_full_scan_setting_lib))
						.setVisibility(View.INVISIBLE);
				mLayoutFullScan.setEnabled(true);
			} else {
				((WPProgressBar) findViewById(R.id.wp_progress_auto_scan_setting_lib))
						.setVisibility(View.INVISIBLE);
				mLayoutAutoScan.setEnabled(true);
			}
			int songScaned = result[0];
			String songScanedStr = songScaned + " "
					+ getString(R.string.toast_song_scanned_plural);
			if (songScaned < 1) {
				songScanedStr = songScaned + " "
						+ getString(R.string.toast_song_scanned);
			}
			int songAdded = result[1];
			String songAddedStr = songAdded + " "
					+ getString(R.string.toast_new_song_plural);
			if (songAdded < 1) {
				songAddedStr = songAdded + " "
						+ getString(R.string.toast_new_song);
			}

			new ToastMessage(getApplicationContext())
					.showShortMessage(songScanedStr + "\n" + songAddedStr);

			Intent i = new Intent(PlayerService.INTENT_PLAYLIST_CHANGED);
			if (mCommand == 1)
				i.putExtra(Common.INTENT_DATA_SONG_PLAYING_CHANGED, true);
			sendBroadcast(i);

			// if (mPlayerService != null) {
			// mPlayerService.resetLaisimWhenScanSong();
			// }
		}
	}

	class TagsUpdater extends AsyncTask<Void, Void, Void> {
		int totalSongCount = 0;
		int tagUpdatedCount = 0;

		@Override
		protected void onPreExecute() {
			((WPProgressBar) findViewById(R.id.wp_progress_scan_setting_lib_rescan_tags))
					.setVisibility(View.VISIBLE);
		}

		@Override
		protected Void doInBackground(Void... params) {
			DataBaseAccess db = DataBaseAccess
					.getInstance(getApplicationContext());
			List<Song> li = db.getAllSong();
			if (li == null || li.size() < 1)
				return null;
			totalSongCount = li.size();
			for (Song s : li) {
				s.updateSongInfo(getApplicationContext());
				db.updateSong(s);
				tagUpdatedCount++;
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			((WPProgressBar) findViewById(R.id.wp_progress_scan_setting_lib_rescan_tags))
					.setVisibility(View.INVISIBLE);
			String songScanedStr = totalSongCount + " "
					+ getString(R.string.toast_song_scanned_plural);
			if (totalSongCount < 1) {
				songScanedStr = totalSongCount + " "
						+ getString(R.string.toast_song_scanned);
			}
			Intent i = new Intent(PlayerService.INTENT_PLAYLIST_CHANGED);

			i.putExtra(Common.INTENT_DATA_SONG_PLAYING_CHANGED, true);
			sendBroadcast(i);

			if (getApplicationContext() == null)
				return;
			new ToastMessage(getApplicationContext())
					.showShortMessage(songScanedStr + "\n");
		}
	}
}
